package com.carhailing.coupons.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.carhailing.common.config.AlipaySign;
import com.carhailing.common.constants.JwtConstants;
import com.carhailing.common.constants.TokenConstants;
import com.carhailing.common.domain.coupons.CouponsVo;
import com.carhailing.common.domain.order.*;
import com.carhailing.common.domain.response.SysUserDto;
import com.carhailing.common.exception.BusinessException;
import com.carhailing.common.interfaces.Codes;
import com.carhailing.common.interfaces.Messages;
import com.carhailing.common.result.Result;
import com.carhailing.common.utils.JwtUtils;
import com.carhailing.coupons.aliPayVo.AlipayVo;
import com.carhailing.coupons.mapper.CouponsOrderMapper;
import com.carhailing.coupons.parent.PayHandle;
import com.carhailing.coupons.service.CouponsOrderService;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Gd
 * @package: com.carhailing.coupons.service.impl
 * @Project: Online_Taxi_Project
 * @Name: CouponsOrderServiceImpl
 * @Date: 2024-7-28 21:43
 */
@Service
public class CouponsOrderServiceImpl implements CouponsOrderService {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private HttpServletRequest servletRequest;

    @Autowired
    private CouponsOrderMapper couponsOrderMapper;

    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 优惠券支付订单
     */
    @Override
    public String paySeckillOrder(AlipaySign alipaySign) throws BusinessException {
//        public String paySeckillOrder(Long orderNumber, String type) throws BusinessException {

//        //判断是否超时
//        Long endPayTime = 1000 * 5L;
//
//        long startPayTime = new Date().getTime() - alipaySign.getTimestamp();
//        // 允许时间范围内请求  否则抛出异常
//        if (startPayTime >=  endPayTime){
//            throw new BusinessException(Codes.TIMEOUT, Messages.TIMEOUT);
//        }
//        // 判断 nonce
//        String nonce = redisTemplate.opsForValue().get("nonce_" + alipaySign.getNonce());
//        if (nonce != null){
//            throw new BusinessException(Codes.REPAY_ERROR, Messages.REPAY_ERROR);
//        }
//        // 判断签名
//        String sign = SecureUtil.md5("orderNumber="+alipaySign.getOrderNumber()+"&timestamp="+alipaySign.getTimestamp()+"&nonce="
//                +alipaySign.getNonce()+"&secretKey="+alipaySign.getSecretKey());
//
//        if (!alipaySign.getSign().equals(sign)){
//            throw new BusinessException(Codes.SIGN_ERROR, Messages.SIGN_ERROR);
//        }
//
//        redisTemplate.opsForValue().set("nonce_"+alipaySign.getNonce(), alipaySign.getNonce(),3, TimeUnit.MINUTES);

        // 支付  策略模式
        PayHandle bean = (PayHandle) applicationContext.getBean(alipaySign.getType());
        String payCarOrder = bean.payCarOrder(alipaySign);
        return payCarOrder;
    }

    /**
     * 支付回调
     * @param request
     */
    @Override
    public void payNotity(HttpServletRequest request) throws BusinessException, AlipayApiException, UnsupportedEncodingException {
        // 获取支付类型
        PayHandle bean = (PayHandle) applicationContext.getBean("ZhiFuBao");
        AlipayVo alipayVo = bean.notifyInfos(request);
        CarPayRecord carPayRecord = couponsOrderMapper.queryCarPayRecord(alipayVo.getOut_trade_no());
        // 判断该订单流水是否存在
        if(null == carPayRecord){
            throw new BusinessException(Codes.PAYNOTITY_ERROR, Messages.PAYNOTITY_ERROR);
        }
        // 0 是在支付的时候存的状态  如果不是初始状态说明收到过回调
        if(!carPayRecord.getPayRecordstatus().equals(0)){
            throw new BusinessException(Codes.PAYNOTITY_REPEAT, Messages.PAYNOTITY_REPEAT);
        }
        // 判断支付金额是否一致
        if(!alipayVo.getTotal_amount().equals(carPayRecord.getPayRecordprice().toString())){
            throw new BusinessException(Codes.TRADE_MONEY_ERROR, Messages.TRADE_MONEY_ERROR);
        }
        CarPayRecord carPayRecord1 = new CarPayRecord();
        carPayRecord1.setPayRecordid(carPayRecord.getPayRecordid());
        if("TRADE_SUCCESS".equals(alipayVo.getTrade_status())) {
            carPayRecord1.setPayRecordstatus(1);
            couponsOrderMapper.updateCarOrder(carPayRecord1);
            //支付成功加积分
            SysUserDto user1 = info().getData();
            if(null != user1){
                Integer userIntegral = user1.getUserIntegral();// 原来积分
                userIntegral = userIntegral + carPayRecord1.getPayRecordprice().intValue();
                // 更新积分
//                couponsOrderMapper.updateUserIntegralByUserId(10,1);
                couponsOrderMapper.updateUserIntegralByUserId(userIntegral,user1.getUserid());
            }
        }else {
            // 支付失败
            carPayRecord1.setPayRecordstatus(2);
            couponsOrderMapper.updateCarOrder(carPayRecord1);
        }
    }

    /**
     * 查询支付流水状态 0  支付中  1  已支付  2  支付失败  3  支付关闭
     */
    @Override
    public List<CarPayRecord> selectCarPayRecordStatus(int status) {
        return couponsOrderMapper.selectCarPayRecordStatus(status);
    }

    @Override
    public void updateCarOrder(CarPayRecord carPayRecord) {
        couponsOrderMapper.updateCarOrder(carPayRecord);
    }

    /**
     * 退款
     */
    @Override
    public void refund(Long orderNumber, String type) throws Exception {
        // 支付成功的订单才能退款
        CarOrder carOrder = couponsOrderMapper.selectByOrderNumber(orderNumber);
        if (null != carOrder) {
            throw new BusinessException(Codes.ORDER_INFO, Messages.ORDER_INFO);
        }
        //  支付状态 0  支付中  1  已支付  2  支付失败  3  支付关闭
        List<CarPayRecord> carPayRecords = couponsOrderMapper.selectPayRecordstatusByOrderNumber(orderNumber);
        if(!CollectionUtils.isEmpty(carPayRecords)){
            carPayRecords.forEach(carPayRecord -> {
                if (!carPayRecord.getPayRecordstatus().equals(1)) {
                    try {
                        throw new BusinessException(Codes.NO_REFUND, Messages.NO_REFUND);
                    } catch (BusinessException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        CarOrderRefund carOrderRefund = new CarOrderRefund();
        carOrderRefund.setRefundOrdernumber(orderNumber);
        carOrderRefund.setRefundMoney(carOrder.getTotalPrice());
        carOrderRefund.setRefundReason("用户申请退款");
        carOrderRefund.setRefundChannel(type);
        carOrderRefund.setRefundStatus(0);
        // 获取用户信息
        Result<SysUserDto> info = info();
        SysUserDto user = info.getData();
        carOrderRefund.setRefundUserphone(user.getUserphone());
        carOrderRefund.setRefundUsername(user.getUsername());
        // 添加一笔退款记录
        couponsOrderMapper.insertCarOrderRefund(carOrderRefund);
        //退款策略
        PayHandle bean = (PayHandle) applicationContext.getBean(type);
        bean.refundCarOrder(orderNumber, carOrder);
    }

    @Override
    public void updateCarOrderRefund(CarOrderRefund carOrderRefund) {
        couponsOrderMapper.updateCarOrderRefund(carOrderRefund);
    }

//    /**
//     * 预留一笔支付流水
//     */
//    private CarPayRecord insertCarPayRecord(Long orderNumber, String type, CarOrder carOrder) {
//        CarPayRecord carPayRecord = new CarPayRecord();
//        carPayRecord.setPayRecordordernumber(orderNumber);
//        // 使用雪花算法生成唯一、有序的 交易订单号    假设workerId和datacenterId都为0
//        SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(0, 0);
//        long payRecordtradenumber = snowflakeIdWorker.nextId();
//        carPayRecord.setPayRecordtradenumber(payRecordtradenumber);
//        carPayRecord.setPayRecorduserid(carOrder.getUserId());
//        carPayRecord.setPayRecordtype(type);
//        // 根据 订单号查询关联的用户表  该用户有什么优惠券  优惠券的抵扣金额
//        CouponsUserRecord couponsUserRecord = couponsOrderMapper.selectCouponsByUserId(carOrder.getUserId());
//        CouponsVo couponsVo = couponsOrderMapper.selectPriceByCouponsId(couponsUserRecord.getRecordId());
//        BigDecimal couponMoney = couponsVo.getCouponMoney();
//        carPayRecord.setPayRecordprice(carOrder.getTotalPrice().subtract(couponMoney));
//        carPayRecord.setPayRecordstatus(0);
//        carPayRecord.setPayRecordtime(new Date());
//        return carPayRecord;
//    }

    /**
     * 获取用户信息
     */
    public Result<SysUserDto> info() {
        String token = servletRequest.getHeader(TokenConstants.TOKEN);
        String userKey = JwtUtils.getUserKey(token);
        String user = redisTemplate.opsForValue().get(JwtConstants.USER_KEY + userKey);
        SysUserDto user1 = JSON.parseObject(user, SysUserDto.class);
        return Result.success(user1);
    }
}
